package com.jsbs.iam.ident.controller;

import com.github.pagehelper.PageInfo;
import com.jsbs.iam.common.core.dto.Result;
import com.jsbs.iam.common.core.utils.Json;
import com.jsbs.iam.common.core.utils.StringUtils;
import com.jsbs.iam.common.core.utils.poi.ExcelUtil;
import com.jsbs.iam.ident.constant.Constants;
import com.jsbs.iam.ident.dto.IamUpdateAccountStatus;
import com.jsbs.iam.ident.dto.IdentityAccountDto;
import com.jsbs.iam.ident.dto.UpdatePasswordDto;
import com.jsbs.iam.ident.entity.IamAccountBase;
import com.jsbs.iam.ident.entity.IamUpdateUserLog;
import com.jsbs.iam.ident.mapper.IdentityMapper;
import com.jsbs.iam.ident.param.IamApplyDetaislParam;
import com.jsbs.iam.ident.service.IamUserLogService;
import com.jsbs.iam.ident.service.IdentityService;
import com.jsbs.iam.ident.vo.IamAccountBaseVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @ClassName: AccountController
 * @Author: tenghuawei
 * @Date: 2022/12/5 15:16
 * @Description:
 */

@SuppressWarnings("all")
@Slf4j
@RestController
@RequestMapping("/iam/ident/identity")
public class IdentityController extends BaseController {

    @Autowired
    IdentityService identityService;

    @Autowired
    private IamUserLogService userLogService;

    @Autowired
    private IdentityMapper identityMapper;

    /**
     * 功能描述：1、账户中心——账号列表分页条件查询（重置按钮可复用该接口）
     * @param identityAccountDto
     * @return Result
     */
    @PostMapping("/queryAccountList")
    public Result queryAccountList(HttpServletRequest request,@RequestBody IdentityAccountDto identityAccountDto) {
        try {
            // 获取当前登录人用户id
            String userCode = (String) request.getHeader(Constants.USER_CODE);
            // 先使用伪数据
//            userCode="admin";
            if (StringUtils.isBlank(userCode)) {
                return Result.failWithMsg("当前登录状态异常！");
            }
            //当前登录人的所属归属租户
            String companyCode = (String) request.getHeader(Constants.COMPANY_CODE);
            //companyCpde先使用伪数据
            companyCode="000001";
            if (StringUtils.isBlank(companyCode)) {
                return Result.failWithMsg("当前归属租户状态异常！");
            }

            if(Objects.nonNull(identityAccountDto.getEmployeeCode()) && identityAccountDto.getEmployeeCode().length()>30){
                return Result.failWithMsg("输入的用户编码长度不可超过30！");
            }
            if(Objects.nonNull(identityAccountDto.getName()) && identityAccountDto.getName().length()>30){
                return Result.failWithMsg("输入的姓名长度不可超过30！");
            }
            identityAccountDto.setCompanyCode(companyCode);
            log.info("Route=>IdentityController method=>queryAccountList 查询账号列表条件入参为：{} ", Json.toJsonString(identityAccountDto));

            PageInfo pageInfo=null;
            if(Constants.ADMIN.equals(userCode)){
                // 超管：查询所有账号列表
                pageInfo = identityService.queryAccountList(identityAccountDto);
            }else{
                // 普管(当前登录管理员的角色编码)：查询当前权限范围中的账号列表
                String adminRoleCode =  (String) request.getHeader(Constants.ADMIN_ROLE_CODE);
                // 先使用伪数据
                adminRoleCode="JS0004";
                if(StringUtils.isBlank(adminRoleCode)){
                    return Result.failWithMsg("角色编码不可为空！");
                }
                // 该角色可查的账号数据权限范围
                identityAccountDto.setAdminRoleCode(adminRoleCode);
                pageInfo = identityService.queryAccountListRange(identityAccountDto);
            }
            if(0==pageInfo.getTotal()){
                return Result.failWithMsg("无数据!");
            }
            return Result.success("账号列表查询成功！",pageInfo);
            }catch (Exception e) {
                log.error("Route=>IdentityController method=>queryAccountList 查询账号列表异常：{}，入参为：{}", e, Json.toJsonString(identityAccountDto));
                return handleException(e,e.getMessage());
            }
    }

    /**
     * 功能描述：2、根据用户id批量删除账号(物理删除)
     * @param userCode
     * @return Result
     */
    @PostMapping("/batchDeleteByUserCode")
    public Result  batchDeleteByUserCode(HttpServletRequest request,@RequestBody List<String> userCode) {
        try {
            //当前登录人的所属归属租户
            String companyCode = (String) request.getHeader(Constants.COMPANY_CODE);
            //companyCpde先使用伪数据
//            companyCode="000001";
            if (StringUtils.isBlank(companyCode)) {
                return Result.failWithMsg("当前归属租户状态异常！");
            }
            if(CollectionUtils.isEmpty(userCode)){
                log.warn("Route=>IdentityController method=>batchDeleteByUserCode 批量删除前台入参为null");
                return Result.fail("请确实勾选信息是否无误!");
            }
            int count = identityService.batchDeleteByUserCode(userCode,companyCode);
            if(0==count){
                return Result.failWithMsg("账户删除失败！");
            }
            log.info("Route=>IdentityController method=>batchDeleteByUserCode 批量删除{}条账户数据成功！",count);
            return Result.successWithMsg("批量删除" +count+ "条账户信息成功！");
        }catch (Exception e){
            log.error("Route=>IdentityController method=>batchDeleteByUserCode 账号批量删除异常：{}", e.getMessage());
            return handleException(e,e.getMessage());
        }

    }

    /**
     * 功能描述：3、停用、启用账号、重置密码（说明：启用账号，传'0'；停用账号，传'1'；重置密码，传'2'）
     * @param iamUpdateAccountStatus
     * @return Result
     */
    @PostMapping("/updateAccountStatus")
    public Result  updateAccountStatus(HttpServletRequest request,@RequestBody IamUpdateAccountStatus iamUpdateAccountStatus) {
        try {
            //当前登录人的所属归属租户
            String companyCode = (String) request.getHeader(Constants.COMPANY_CODE);
            //companyCpde先使用伪数据
//            companyCode="000001";
            if (StringUtils.isBlank(companyCode)) {
                return Result.failWithMsg("当前归属租户状态异常！");
            }
            if(CollectionUtils.isEmpty(iamUpdateAccountStatus.getUserCode())){
                log.warn("Route=>IdentityController method=>updateAccountStatus 未勾选任何账户信息，请勾选至少一条用户列表信息！");
                return Result.failWithMsg("请勾选至少一条用户列表信息!");
            }
            if(null==iamUpdateAccountStatus.getOperation()){
                log.warn("Route=>IdentityController method=>updateAccountStatus 无任何操作类型！");
                return Result.failWithMsg("请确定您的类型操作！");
            }
            iamUpdateAccountStatus.setCompanyCode(companyCode);
            log.info("Route=>IdentityController method=>updateAccountStatus 启用/停用/重置密码时前台入参:{}",Json.toJsonString(iamUpdateAccountStatus));
            Integer initOperation = iamUpdateAccountStatus.getOperation();

            //①停用或启用账户
            if(0==initOperation || 1==initOperation){
                Integer accountStatus= initOperation==0?1:0;
                iamUpdateAccountStatus.setAccountStatus(accountStatus);
                int updateCount = identityService.updateAccountStatus(iamUpdateAccountStatus);
                if(0==updateCount){
                    return Result.failWithMsg("停用或启用账户操作失败！");
                }
                return Result.successWithMsg(String.format("%d条账户启用或停用，更改成功!",updateCount));
            }

            //②重置密码
            if(2==iamUpdateAccountStatus.getOperation()){
                if(!identityService.resetPassword(iamUpdateAccountStatus)){
                    return Result.failWithMsg("重置密码失败！");
                }
                return Result.successWithMsg("重置密码成功！");
            }
            return  Result.failWithMsg("停用、启用账号、重置密码失败！");
            }catch (Exception e){
                log.error("Route=>IdentityController method=>updateAccountStatus 停用、启用账号、重置密码接口异常：{}", e.getMessage());
                return handleException(e,e.getMessage());
            }
    }

    /**
     * 功能描述：4、账号导出
     * @param
     * @return
     */
    @PostMapping("/accountExport")
    public void accountExport(@RequestBody IdentityAccountDto identityAccountDto,HttpServletRequest request,HttpServletResponse response){
        try {
            //当前登录人的所属归属租户
            String companyCode = (String) request.getHeader(Constants.COMPANY_CODE);
            //companyCpde先使用伪数据
//            companyCode="000001";
            if (StringUtils.isBlank(companyCode)) {
                throw new RuntimeException("当前归属租户状态异常！");
            }
            identityAccountDto.setCompanyCode(companyCode);
            log.info("Route=>IdentityController method=>accountExport 账号导出前台入参:{}",Json.toJsonString(identityAccountDto));
            List<IamAccountBaseVo> iamAccountBaseVos = identityService.queryExcelAccountList(identityAccountDto);
            identityAccountDto.setCurrPage(0);
            identityAccountDto.setPageSize(iamAccountBaseVos.size());
            if (iamAccountBaseVos.size() > 5000) {
                throw new RuntimeException("导出数据超5W条，请分批次导出！");
            }
            if (CollectionUtils.isEmpty(iamAccountBaseVos)) {
                throw new RuntimeException("导出数据为空！");
            }
            long currentTimeMillis = System.currentTimeMillis();
            ExcelUtil<IamAccountBaseVo> util = new ExcelUtil<IamAccountBaseVo>(IamAccountBaseVo.class);
            String title="账号统计表"+currentTimeMillis+".xlsx";
            String excelFileName="账号统计表"+currentTimeMillis+".xlsx";
            util.exportExcel(response,iamAccountBaseVos, "账号统计表",title,excelFileName);
            log.info("Route=>IdentityController method=>accountExport 导出成功！");
        }catch (RuntimeException e){
            log.error("Route=>IdentityController method=>accountExport 账号导出异常:{}",e.getMessage());
        } catch (UnsupportedEncodingException e) {
            log.error("Route=>IdentityController method=>accountExport 账号导出异常:{}",e.getMessage());
        }
    }

    /**
     * 功能描述：导入用户数据
     * @param file
     * @param request
     * @return Result
     */
    @PostMapping("/accountImport")
    public Result accountImport(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws Exception{
    try {
        //当前登录人的所属归属租户
        String companyCode = (String) request.getHeader(Constants.COMPANY_CODE);
        //companyCpde先使用伪数据
//        companyCode="000001";
        if (StringUtils.isBlank(companyCode)) {
            throw new RuntimeException("当前归属租户状态异常！");
        }
        if (Objects.isNull(file)) {
            throw new RuntimeException("所选的导入文件数据为空，请重新导入！");
        }
        ExcelUtil<IamAccountBaseVo> util = new ExcelUtil<IamAccountBaseVo>(IamAccountBaseVo.class);
        List<IamAccountBaseVo> accountList = util.importExcel(file.getInputStream());
        //操作人
        String userName = (String) request.getHeader("userName");
        // userName先使用伪数据
        userName="admin";
        String anImport = identityService.accountImport(accountList, companyCode, userName);
        log.info("Route=>IdentityController method=>accountImport 导入成功！");
        return Result.successWithMsg(anImport);
        } catch (RuntimeException e) {
        log.error("Route=>IdentityController method=>accountImport 账号导入异常:{}",e.getMessage());
        return handleException(e,e.getMessage());
        }
    }

    /**
     * 根据账户id查询账户数据
     * @param accountId
     * @return
     */
    @PostMapping("/getAccountBase")
    public Result getAccountBase(@RequestParam("accountId") String accountId,@RequestParam("companyCode") String companyCode) {
        log.info("Route=>IdentityController method=>getAccountBase 根据账户id查询账户数据：{}", accountId);
        try {
            if (StringUtils.isEmpty(accountId)) {
                log.info("根据账户id查询账户数据失败,参数非法{}", accountId);
                return Result.failWithMsg("账户id为空");
            }
            List<IamAccountBaseVo> userTypeExtendedFields = identityService.getAccountBase(accountId,companyCode);
            return new Result(Result.SUCCESS, "根据账户id查询账户数据成功", userTypeExtendedFields);
        } catch (Exception e) {
            log.error("Route==>IdentityController method=>getAccountBase 根据账户id查询账户数据异常，入参：{}，异常：{}", accountId, e);
            return handleException(e);
        }
    }

    /**
     * 功能描述：根据用户id查看的应用详情
     * @param iamApplyDetaislParam
     * @param request
     * @return Result
     */
    @PostMapping("/getApplicationDetails")
    public Result getApplicationDetails(HttpServletRequest request, @RequestBody IamApplyDetaislParam iamApplyDetaislParam){
        try {
            // 获取当前登录人
            String userCode = (String) request.getHeader(Constants.USER_CODE);
            //先使用伪数据
//            userCode="admin";
            if (StringUtils.isBlank(userCode)) {
                return Result.failWithMsg("当前登录状态异常！");
            }
            //归属租户
            String companyCode = (String) request.getHeader(Constants.COMPANY_CODE);
            //companyCpde先使用伪数据
            companyCode="000001";
            if (StringUtils.isBlank(companyCode)) {
                return Result.failWithMsg("当前归属租户状态异常！");
            }
            iamApplyDetaislParam.setCompanyCode(companyCode);
            Result result = identityService.getApplicationDetails(iamApplyDetaislParam);
            return Result.success("查询该账号的应用详情成功",result.getData());

        } catch (RuntimeException e) {
            log.error("Route=>IdentityController method=>applicationDetails 查看应用详情异常:{}",e.getMessage());
            return handleException(e,e.getMessage());
        }
    }

    @PostMapping("/updatePassword")
    public Result updatePassword (@RequestBody UpdatePasswordDto updatePasswordDto,HttpServletRequest request) {
        String newPassword = updatePasswordDto.getNewPassword();
        String oldPassword = updatePasswordDto.getOldPassword();
        String account = updatePasswordDto.getAccount();
        Cookie[] cookies = request.getCookies();
        String userCode = null;
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals(Constants.USER_CODE)) {
                userCode = cookie.getValue();
            }
        }
//        String userCode = request.getHeader(Constants.USER_CODE);
        IamAccountBase accountBase = null;
        if (StringUtils.isNotEmpty(userCode)) {
            accountBase = identityMapper.queryByUserCode(userCode, null);
        }
        String companyCode = (String) request.getHeader(Constants.COMPANY_CODE);
        try {
            int i = identityService.updatePassword(account, newPassword, oldPassword);
            if(i>0){
                if (accountBase != null) {
                    IamUpdateUserLog iamUpdateUserLog = convertUpdateLog(accountBase, companyCode, true);
                    userLogService.saveIamUpdateUserLog(iamUpdateUserLog);
                }
                return Result.success("密码修改成功",i);
            } else {
                if (accountBase != null) {
                    IamUpdateUserLog iamUpdateUserLog = convertUpdateLog(accountBase, companyCode, false);
                    userLogService.saveIamUpdateUserLog(iamUpdateUserLog);
                }
                return Result.failWithMsg("密码修改失败");
            }
        } catch (Exception e) {
            if (accountBase != null) {
                IamUpdateUserLog iamUpdateUserLog = convertUpdateLog(accountBase, companyCode, false);
                userLogService.saveIamUpdateUserLog(iamUpdateUserLog);
            } else {
                IamUpdateUserLog iamUpdateUserLog = new IamUpdateUserLog();
                iamUpdateUserLog.setUserCode(account);
                iamUpdateUserLog.setUpdateType(Constants.LOG_Update);
                iamUpdateUserLog.setUpdateStatus(false);
                iamUpdateUserLog.setCreateTime(new Date());
                iamUpdateUserLog.setModifyTime(new Date());
                userLogService.saveIamUpdateUserLog(iamUpdateUserLog);
            }
            log.info("Route=>IdentityController method=>updatePassword 修改密码失败，详情为{}",e);
            return handleException(e,e.getMessage());
        }

    }

    private IamUpdateUserLog convertUpdateLog (IamAccountBase accountBase,String companyCode,Boolean status) {
        //根据用户名查询信息填充iamUpdateUserLog request取ip
        IamUpdateUserLog iamUpdateUserLog = new IamUpdateUserLog();
        iamUpdateUserLog.setUserCode(accountBase.getUserCode());
        iamUpdateUserLog.setUserName(accountBase.getName());
        iamUpdateUserLog.setUpdateType(Constants.LOG_Update);
        iamUpdateUserLog.setUpdateStatus(status);
        iamUpdateUserLog.setCompanyCode(companyCode);
        iamUpdateUserLog.setCreatePerson(accountBase.getName());
        iamUpdateUserLog.setCreateTime(new Date());
        iamUpdateUserLog.setModifyTime(new Date());
        return iamUpdateUserLog;
    }

}


